package com.lijin.otp.util;


import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.alibaba.fastjson.JSONObject;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeWriter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import net.nullschool.util.DigitalRandom;

/**
 * 二维码生成类工具
 * Created by gold-jx on 2017/7/13.
 */
public class QRCodeUtil {

    private final static QRCodeWriter WRITER = new QRCodeWriter();

    /**
     * 二维码宽度
     */
    private final static int QR_WIDTH = 200;

    /**
     * 二维码高度
     */
    private final static int QR_HEIGHT = 200;

    /**
     * 图像类型
     */
    private final static String FORMAT = "png";

    /**
     * 根据用户名和密钥生成二维码
     *
     * @param username 用户名
     * @param secret 密钥
     * @return 二维码图片
     */
    public static BitMatrix generateOtpQR(String username, String secret) throws WriterException {

        JSONObject json = new JSONObject();
        json.put(
                "zxing",
                "https://github.com/zxing/zxing/tree/zxing-3.0.0/javase/src/main/java/com/google/zxing");
        json.put("author", "shihy");
        String content = json.toJSONString();// 内容

        /*String content = "otpauth://totp/" + username + ":" + username + "@jxinternet"
                + "?secret=" + secret + "&issuer=JXINTERNET";*/

        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

        return WRITER.encode(content, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);

    }


    /**
     * 输出二维码图片到指定目录
     * @param bitMatrix 二维码图片
     * @param filePath 文件路径
     * @param fileName 文件名
     * @throws WriterException
     * @throws IOException
     */
    public static void outputOtpQR(BitMatrix bitMatrix, String filePath, String fileName) throws WriterException, IOException {
        //String filePath = "E://";
        // String fileName = "zxing.png";
        Path path = FileSystems.getDefault().getPath(filePath, fileName);

        MatrixToImageWriter.writeToPath(bitMatrix, FORMAT, path);// 输出图像

    }


    /**
     * 输出二维码到浏览器
     * @param username
     * @param secret
     * @param response
     * @throws WriterException
     * @throws IOException
     */
    public static void writerStreamToResponse(String username, String secret, HttpServletResponse response) throws WriterException, IOException {

        BitMatrix matrix = generateOtpQR(username, secret);

        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/png");

        MatrixToImageWriter.writeToStream(matrix, "png",response.getOutputStream());
    }

    /**
     * 生成秘钥
     * @return 秘钥
     */
    public static String generateSecret() {
        DigitalRandom random = new DigitalRandom();
        List<String> pickFrom = Lists.newArrayList("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z");
        List<String> result = Lists.newArrayList();

        IntStream.range(0, 16).forEach(index -> {
            int pickIndex = random.nextInt(0, 26 - index);
            result.add(pickFrom.get(pickIndex));
            pickFrom.remove(pickIndex);
        });

        return Joiner.on("").join(result);
    }


    public  static void  toDecodeOtp(String filePath){

        //String filePath = "D://zxing.png";
        BufferedImage image;
        try {
            image = ImageIO.read(new File(filePath));
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码
            JSONObject content = JSONObject.parseObject(result.getText());
            System.out.println("图片中内容：  ");
            System.out.println("author： " + content.getString("author"));
            System.out.println("zxing：  " + content.getString("zxing"));
            System.out.println("图片中格式：  ");
            System.out.println("encode： " + result.getBarcodeFormat());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
    }



}







